package igz.fleaxy.video  {
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.NetStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.media.SoundTransform;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.ui.Mouse;
	import flash.utils.Timer;
	import igz.fleaxy.ui.LinkUi;
	import igz.fleaxy.ui.preloader.RadialPreloaderUi;
	import igz.fleaxy.util.ImageUtil;
	import igz.fleaxy.util.ObjectUtil;
	
	/**
	 * @author Intelygenz | www.intelygenz.com
	 */
	public class VideoManager extends Sprite {

		protected var _VideoUri:String;
		protected var _Video:Video;
		public function get $Video() : Video {
			return _Video;
		}
		protected var _NetConnection:NetConnection;
		protected var _NetStream:NetStream;
		public function get $NetStream() : NetStream {
			return _NetStream;
		}
		protected var _NetStreamClient:NetStreamClient;
		public function get $NetStreamClient() : NetStreamClient {
			return _NetStreamClient;
		}
		
		protected var _SoundTimer : Timer;
		protected var _ReplayImg : LinkUi;
		protected var _CallBackReplay : Function;

		protected var _BufferLoading : RadialPreloaderUi;
		protected var _BufferTimer : Timer;

		public function VideoManager() {
			_NetConnection = new NetConnection();
            _NetConnection.addEventListener(NetStatusEvent.NET_STATUS, _OnNetStatus);
            _NetConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, _NetConnection_OnSecurityError);
			_NetConnection.connect(null);
			
			_CreateBuffer();
		}

		protected var _Settings:Object;
		public function $Play(p_videoUri:String, p_settings:Object) : void {
			_Settings = { "onFinish" : null
						, "onPlaying" : null
						, "onMetaData" : null
						, "onCuePoint" : null
						, "width"  : 320
						, "height" : 180
						, "bufferTime" : 15
						};
						
			ObjectUtil.$Merge(p_settings, _Settings);
			_VideoUri = p_videoUri;
		
			_StartConnect();
		}

		protected function _StartConnect() : void {
			_NetStreamClient = new NetStreamClient(_Settings["onMetaData"], _Settings["onCuePoint"]);
			_NetStream = new NetStream(_NetConnection);
			_NetStream.addEventListener(NetStatusEvent.NET_STATUS, _OnNetStatus);
			_NetStream.client = _NetStreamClient;
			
			_NetStream.bufferTime = _Settings["bufferTime"];
			
			if ( _Video != null ) {
				_Video.parent.removeChild( _Video );
			}
			
			_Video = new Video(_Settings["width"], _Settings["height"]);
			_Video.attachNetStream(_NetStream);
			_Video.smoothing = true;
			_NetStream.play(_VideoUri);
			
			
			addChild(_Video);
			_ShowBufferLoading();
			if ( _ReplayImg != null ) {
				$DeactivateReplay();
			}
			
			
			
		}
		
		

		protected function _Video_OnEnterFrame(p_event:Event) : void {
			if ( _NetStream != null && _NetStreamClient != null && _NetStreamClient.$MetaDataInfo != null ) {
				if ( Math.ceil(_NetStream.time) >= Math.floor(_NetStreamClient.$MetaDataInfo.duration) ) {
					_Video.removeEventListener(Event.ENTER_FRAME, _Video_OnEnterFrame);					
					trace(" _Video_OnEnterFrame FINISH");
					trace( _Settings["onFinish"]  );
					if ( _Settings["onFinish"] != null ) {
						_Settings["onFinish"]();
					}
				}
				else if ( _Settings["onPlaying"] != null ) {
					_Settings["onPlaying"]();
				}
			}
		}
		
		

		protected function _OnNetStatus(p_netStatusEvent:NetStatusEvent) : void {
            switch (p_netStatusEvent.info.code) {
                case "NetConnection.Connect.Success":
					if ( _NetStreamClient!=null ) {
						_StartConnect();
					}
                    break;
				case "NetStream.Play.Start" :
					if ( ! _Video.hasEventListener(Event.ENTER_FRAME) ) {
						_Video.addEventListener(Event.ENTER_FRAME, _Video_OnEnterFrame);
					}
					break;
                case "NetStream.Play.StreamNotFound":
                    trace("_OnNetStatus -> StreamNotFound -> " + _VideoUri);
                    break;
				case "NetStream.Buffer.Empty" :
					if ( Math.ceil(_NetStream.time) < Math.floor(_NetStreamClient.$MetaDataInfo.duration) ) {
						_ShowBufferLoading();
					}
					break;
				case "NetStream.Buffer.Full" :
					_HideBufferLoading();
					break;
            }
			
			
		}

		protected function _NetConnection_OnSecurityError(p_securityErrorEvent:SecurityErrorEvent) : void {
			trace("_NetConnection_OnSecurityError: " + p_securityErrorEvent);
		}

		public function $Stop() : void {
			if ( _NetStream != null ) {
				if ( _Video.hasEventListener(Event.ENTER_FRAME) ) {
					_Video.removeEventListener(Event.ENTER_FRAME, _Video_OnEnterFrame);
				}
				_NetStream.close();
				_HideBufferLoading();
			}
		}

		public function $Pause( p_fadeOut : Boolean = false ) : void {
			if ( _NetStream != null ) {
				if ( _Video.hasEventListener(Event.ENTER_FRAME) ) {
					_Video.removeEventListener(Event.ENTER_FRAME, _Video_OnEnterFrame);
				}
				if ( ! p_fadeOut ) {
					_NetStream.soundTransform = new SoundTransform(0);
					_NetStream.pause();
				} else {
					if ( _NetStream.soundTransform.volume > 0 ){
						_FadeOut();
					} else {
						_NetStream.soundTransform = new SoundTransform(0);
						_NetStream.pause();
					}
				}			
				_HideBufferLoading();
				
			}
		}
		
		public function $Resume( p_FadeIn : Boolean = false ) : void {
			if ( _NetStream != null ) {
				if ( !_Video.hasEventListener(Event.ENTER_FRAME) ) {
					_Video.addEventListener(Event.ENTER_FRAME, _Video_OnEnterFrame);
				}
				if ( ! p_FadeIn ) {
					_NetStream.soundTransform = new SoundTransform(1);
				} else {
					if ( _SoundTimer ) {
						_SoundTimer.stop();
					}
					if ( _NetStream.soundTransform.volume < 1 ){
						_FadeIn();
					} else {
						_NetStream.soundTransform = new SoundTransform(1);
					}
				}
				
				_NetStream.resume();
			}
		}
		
		public function $Seek( p_toCue : Number ) :  void {
			_NetStream.seek( p_toCue );
			
		}
		
		protected function _FadeOut() : void {
			
			_SoundTimer = new Timer( 50 );
			_SoundTimer.addEventListener(TimerEvent.TIMER, _FadeOutSound );
			_SoundTimer.start();
		}
		
		protected function _FadeOutSound( p_TimerEvent : TimerEvent ) : void {
			_NetStream.soundTransform = new SoundTransform( _NetStream.soundTransform.volume - 0.1 );
			if ( _NetStream.soundTransform.volume <= 0 ) {
				_SoundTimer.stop();
				$Pause();
			}
		}
		
		protected function _FadeIn() : void {
			_SoundTimer = new Timer( 50 );
			_SoundTimer.addEventListener(TimerEvent.TIMER, _FadeInSound );
			_SoundTimer.start();
		}
		
		protected function _FadeInSound( p_TimerEvent : TimerEvent ) : void {		
			_NetStream.soundTransform = new SoundTransform( _NetStream.soundTransform.volume + 0.1 );
			
			if ( _NetStream.soundTransform.volume >= 1 ) {
				_SoundTimer.stop();
			}
		}
		
		public function $SetReplay( p_replayImg : DisplayObject, p_function : Function ) : void {
			_ReplayImg = new LinkUi( p_replayImg,  { 
								  "onClick" : p_function
								, "onRollOver" : _ReplayRollOver
								, "onRollOut" : _ReplayRollOut
									}	);
			
			
			_ReplayImg.visible = false;
			addChild( _ReplayImg );
			_ReplayImg.addEventListener( MouseEvent.CLICK, _ReplayVideo );
		}
		
		
		public function $ActivateReplay() : void {
			_ReplayImg.y = ( this.height - _ReplayImg.height ) * 0.5;
			_ReplayImg.x = ( this.width - _ReplayImg.width ) * 0.5;
			_ReplayImg.$Enable();
			_ReplayImg.alpha = 0.9;
			_ReplayImg.visible = true;
			_Video.alpha = 0.2;
		}
		
		public function $DeactivateReplay() : void {
			_ReplayImg.visible = false;
			_ReplayImg.alpha = 0;
			_ReplayImg.$Disable();
			_Video.alpha = 1;
		}
		
		protected function _ReplayVideo( p_mouseEvent : MouseEvent ) : void {
			_NetStream.pause();
			_NetStream.seek( 0 );
			_NetStream.resume();
		}
		
		protected function _ReplayRollOver( p_mouseEvent : MouseEvent ) : void {
			_ReplayImg.alpha = 1;
		}
		
		protected function _ReplayRollOut( p_mouseEvent : MouseEvent ) : void {
			_ReplayImg.alpha = 0.9;
		}
		
		//BUFFER FUNCTIONS
		protected function _CreateBuffer() : void {
			_BufferTimer = new Timer( 10 );
			_BufferTimer.addEventListener(TimerEvent.TIMER, _BufferPreloadUpdate );
			
			_BufferLoading = new RadialPreloaderUi();
			addChild( _BufferLoading );
			_BufferLoading.visible = false;
		}
		
		protected function _ShowBufferLoading() : void {
			_BufferTimer.start();
			
			if ( ( _Video != null )  && (_BufferLoading != null ) ) {
				swapChildren( _BufferLoading, _Video );
			}
			_BufferLoading.visible = true;
			_BufferLoading.y = ( _Video.height - _BufferLoading.height ) * 0.5;
			_BufferLoading.x = ( _Video.width - _BufferLoading.width ) * 0.5;
		}
		
		protected function _HideBufferLoading() : void {
			_BufferLoading.visible = false;
			_BufferTimer.stop();
		}
		
		protected function _BufferPreloadUpdate( p_timerEvent : TimerEvent ) : void {
			
			if ( _BufferTimer.currentCount > 100 ) {
				_BufferTimer.reset();
				_BufferTimer.start();
			}
			
			_BufferLoading.$SetValue( _BufferTimer.currentCount );
		}

	}

}